(define (caar x) (builtin car (builtin car x)))
(define (cadr x) (builtin car (builtin cdr x)))
(define (cdar x) (builtin cdr (builtin car x)))
(define (cddr x) (builtin cdr (builtin cdr x)))
(define (caaar x) (builtin car (builtin car (builtin car x))))
(define (caadr x) (builtin car (builtin car (builtin cdr x))))
(define (cadar x) (builtin car (builtin cdr (builtin car x))))
(define (caddr x) (builtin car (builtin cdr (builtin cdr x))))
(define (cdraar x) (builtin cdr (builtin car (builtin car x))))
(define (cdadr x) (builtin cdr (builtin car (builtin cdr x))))
(define (cddar x) (builtin cdr (builtin cdr (builtin car x))))
(define (cdddr x) (builtin cdr (builtin cdr (builtin cdr x))))
(define (caaaar x) (builtin car (builtin car (builtin car (builtin car x)))))
(define (caaadr x) (builtin car (builtin car (builtin car (builtin cdr x)))))
(define (caadar x) (builtin car (builtin car (builtin cdr (builtin car x)))))
(define (caaddr x) (builtin car (builtin car (builtin cdr (builtin cdr x)))))
(define (cadaar x) (builtin car (builtin cdr (builtin car (builtin car x)))))
(define (cadadr x) (builtin car (builtin cdr (builtin car (builtin cdr x)))))
(define (caddar x) (builtin car (builtin cdr (builtin cdr (builtin car x)))))
(define (cadddr x) (builtin car (builtin cdr (builtin cdr (builtin cdr x)))))
(define (cdaaar x) (builtin cdr (builtin car (builtin car (builtin car x)))))
(define (cdaadr x) (builtin cdr (builtin car (builtin car (builtin cdr x)))))
(define (cdadar x) (builtin cdr (builtin car (builtin cdr (builtin car x)))))
(define (cdaddr x) (builtin cdr (builtin car (builtin cdr (builtin cdr x)))))
(define (cddaar x) (builtin cdr (builtin cdr (builtin car (builtin car x)))))
(define (cddadr x) (builtin cdr (builtin cdr (builtin car (builtin cdr x)))))
(define (cdddar x) (builtin cdr (builtin cdr (builtin cdr (builtin car x)))))
(define (cddddr x) (builtin cdr (builtin cdr (builtin cdr (builtin cdr x)))))


(define (length-aux l n)
  (if (null? l)
      n
      (length-aux (cdr l) (+ n 1))))

(define (length l) (length-aux l 0))

(define (list? lst)
  (if (builtin null? lst)
      #f
      (if (pair? lst)
          (list? (builtin cdr lst))
          #f)))

(define (assq k l)
  (if (builtin null? l)
      #f
      (if (builtin eq? k (caar l))
          (builtin car l)
          (assq k (builtin cdr l)))))

(define (length-aux lst i)
  (if (builtin null? lst)
      i
      (length-aux (builtin cdr lst) (+ i 1))))

(define (length lst) (length-aux lst 0))

(define (append l m)
  (if (builtin null? l)
      m
      (builtin cons (builtin car l) (append (builtin cdr l) m))))

(define (fold fn init lst)
  (if (builtin null? lst)
      init
      (fn (builtin car lst) (foldr fn init (builtin cdr lst)))))

(define (foldl fn init lst)
  (if (builtin null? lst)
      init
      (foldl fn (fn init (builtin car lst)) (builtin cdr lst))))

(define (foldr fn init lst)
  (if (builtin null? lst)
      init
      (fn (builtin car lst) (foldr fn init (builtin cdr lst)))))

(define (map fn lst)
  (if (builtin null? lst)
      '()
      (builtin cons (fn (builtin car lst)) (map fn (builtin cdr lst)))))

(define (map2 fn lst1 lst2)
  (if (if (builtin null? lst1) (builtin null? lst2) #f)
      '()
      (builtin cons (fn (builtin car lst1) (builtin car lst2)) (map2 fn (builtin cdr lst1) (builtin cdr lst2)))))

(define (for-each fn lst)
  (if (builtin null? lst)
      '()
      (begin (fn (builtin car lst)) (for-each fn (builtin cdr lst)))))

(define (memq elt l)
  (if (builtin null? l) #f (if (builtin eq? elt (builtin car l)) #t (memq elt (builtin cdr l)))))

(define (revappend l t)
 (if (builtin null? l)
     t
     (revappend (builtin cdr l) (builtin cons (builtin car l) t))))
(define (reverse l) (revappend l '()))
